package com.zc.app.sys.controller;

import com.zc.app.shiro.utils.JsonUtils;
import com.zc.app.sys.dao.peer.SystemMenuPeer;
import com.zc.app.sys.dao.peer.SystemUserPeer;
import com.zc.app.sys.dao.peer.User;
import com.zc.app.sys.service.SystemMenuService;
import com.zc.app.sys.service.SystemUserService;
import com.zc.framework.common.bean.AjaxResult;
import com.zc.framework.system.BaseController;
import com.zc.framework.system.SessionUtil;
import com.zc.framework.utils.MD5Utils;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * Created by zc on 2016/9/2.
 */
@Controller
public class LoginController extends BaseController {

    private static final Logger logger = LogManager.getLogger(LoginController.class);

    @Autowired
    private SystemUserService systemUserService;

    @Autowired
    private SystemMenuService systemMenuService;

    @InitBinder({ "systemUser" })
    public void initBinderSystemUser(WebDataBinder binder) {
        binder.setFieldDefaultPrefix("systemUser.");
    }

    @RequestMapping(value="/add", method=RequestMethod.POST)
    public String addUser(User user,
                          @RequestParam(value = "username",required = false)String username,
                          @RequestParam(value = "nickname",required = false)String nickname,
                          @RequestParam(value = "myfiles",required = false) MultipartFile[] myfiles, HttpServletRequest request) throws IOException {
        //如果只是上传一个文件，则只需要MultipartFile类型接收文件即可，而且无需显式指定@RequestParam注解
        //如果想上传多个文件，那么这里就要用MultipartFile[]类型来接收文件，并且还要指定@RequestParam注解
        //并且上传多个文件时，前台表单中的所有<input type="file"/>的name都应该是myfiles，否则参数里的myfiles无法获取到所有上传的文件
        for(MultipartFile myfile : myfiles){
            if(myfile.isEmpty()){
                System.out.println("文件未上传");
            }else{
                System.out.println("文件长度: " + myfile.getSize());
                System.out.println("文件类型: " + myfile.getContentType());
                System.out.println("文件名称: " + myfile.getName());
                System.out.println("文件原名: " + myfile.getOriginalFilename());
                System.out.println("========================================");
                //如果用的是Tomcat服务器，则文件会上传到\\%TOMCAT_HOME%\\webapps\\YourWebProject\\WEB-INF\\upload\\文件夹中
                String realPath = request.getSession().getServletContext().getRealPath("/WEB-INF/upload");
                //这里不必处理IO流关闭的问题，因为FileUtils.copyInputStreamToFile()方法内部会自动把用到的IO流关掉，我是看它的源码才知道的
//                FileUtils.copyInputStreamToFile(myfile.getInputStream(), new File(realPath, myfile.getOriginalFilename()));
            }
        }
//        users.put(user.getUsername(), user);
        return "redirect:/user/list";
    }

    @RequestMapping(value = "/admin/index",method = {RequestMethod.GET})
    public ModelAndView adminIndex(HttpServletRequest request, Model model){
        ModelAndView pageView = new ModelAndView("admin/login");
        pageView.setViewName("admin/index");
        List<SystemMenuPeer> menuList = systemMenuService.getAllMenu();
        request.setAttribute("menuList",  menuList);
        return pageView;
    }


    @RequestMapping(value = {"/","/login"},method = {RequestMethod.GET})
    public ModelAndView showLoginPage(HttpServletRequest request, Model model){
        logger.info("showLoginPage");
        ModelAndView pageView = new ModelAndView("admin/login");

        //查看上下文中是否该用户已经登录了
        SystemUserPeer user = systemUserService.getCurrentUser();
        //如果已经登录，则跳转到管理首页
        if(user.getAccountId() != null){
            pageView.setViewName("admin/index");
            request.setAttribute("currentUser", user.getLoginName());
            SessionUtil.setAttribute(request, "SYSTEM_USERINFO", user);
            List<SystemMenuPeer> menuList = systemMenuService.getAllMenu();
            request.setAttribute("menuList",  menuList);

            return pageView;
        }
        return pageView ;//new ModelAndView("admin/login");
    }

    @RequestMapping(value = "/unauthorized", method = {RequestMethod.GET})
    public ModelAndView unauthorized(){

        return new ModelAndView("unauthorized");
    }

    @RequestMapping(value = "/test",method = {RequestMethod.GET})
    public String testPage(){
        logger.info("testPage");
        return "test";
    }


    @RequestMapping(value = "/login", method = RequestMethod.POST)
    @ResponseBody
    public AjaxResult login(@ModelAttribute("systemUser") SystemUserPeer systemUser,
                            HttpServletRequest request,
                            HttpServletResponse response, Model model){

        if(StringUtils.isEmpty(systemUser.getLoginName())){
            return fail(false,"账号不能为空!");
        }
        if(StringUtils.isEmpty(systemUser.getLoginPassword())){
            return fail(false,"密码不能为空!");
        }

        systemUser.setLoginPassword(MD5Utils.getMD5(systemUser.getLoginPassword()));
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(systemUser.getLoginName(), systemUser.getLoginPassword());
//        token.setRememberMe(true);
        try{
            subject.login(token);

            if(!subject.isAuthenticated()){
                logger.error("login error");
                return fail(false,"登录失败");
            }
            SystemUserPeer user = systemUserService.selectByLoginName(systemUser.getLoginName());
            SessionUtil.setAttribute(request, "SYSTEM_USERINFO", user);
            logger.info(JsonUtils.writeValueAsString(user));
        } catch (UnknownAccountException e) {
            return fail(false, "该账号不存在!");
        } catch (DisabledAccountException e) {
            return fail(false, "该账号已被冻结!");
        } catch (IncorrectCredentialsException e) {
            return fail(false, "密码错误");
        } catch (RuntimeException e) {
            return fail(false, "未知错误,请联系管理员!");
        } catch (IOException e) {
            logger.error(e.getMessage(),e);
            return fail(false, e.getMessage());
        }
        return success(true);
    }

    /**
     * 退出
     * @return
     */
    @RequestMapping(value = "/logout", method = RequestMethod.GET)
    public String logout() {
        logger.info("logout");
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return redirectTo("/login");
    }



    @RequestMapping(value = "/menu", method = RequestMethod.GET)
    @ResponseBody
    public List<SystemMenuPeer> getMenu(){
        List<SystemMenuPeer> menuList = systemMenuService.getAllMenu();
        return menuList;
    }
}
